home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 February
/
EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso
/
earcd
/
comm2
/
termsorc.lha
/
Extras
/
Source
/
term-source.lha
/
termDial.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-26
|
42KB
|
1,885 lines
/*
** termDial.c
**
** The dialing routine as called by the phonebook
**
** Copyright © 1990-1995 by Olaf `Olsen' Barthel
** All Rights Reserved
**
** :ts=4
*/
#include "termGlobal.h"
/* Panel gadget IDs. */
enum { GAD_CALLING=1,GAD_TIME,GAD_NOTE,
GAD_SKIP,GAD_REMOVE,GAD_ONLINE,GAD_ABORT
};
STATIC VOID __stdargs
PrintBox(LayoutHandle *Handle,LONG Box,LONG Line,STRPTR String,...)
{
UBYTE LocalBuffer[256];
va_list VarArgs;
va_start(VarArgs,String);
VSPrintf(LocalBuffer,String,VarArgs);
va_end(VarArgs);
LT_SetAttributes(Handle,Box,
LABX_Index, Line,
LABX_Text, LocalBuffer,
TAG_DONE);
}
STATIC BOOL __regargs
SendSomeCommand(LayoutHandle *Handle,STRPTR Command,STRPTR Message,STRPTR ErrorMessage)
{
PrintBox(Handle,GAD_NOTE,0,Message);
FlowInit(TRUE);
SerialCommand(Command);
WaitTime(1,0);
HandleSerial();
if(FlowInfo . Changed && FlowInfo . Error)
{
PrintBox(Handle,GAD_NOTE,0,ErrorMessage);
WakeUp(Handle -> Window,SOUND_ERROR);
return(TRUE);
}
else
return(FALSE);
}
/* BuildName(STRPTR Name):
*
* Build a file name from a BBS name and the current date.
*/
STATIC VOID __regargs
BuildName(STRPTR Name,STRPTR Date)
{
if(Date[0])
{
WORD NameLen = strlen(Name),
DateLen = strlen(Date),
Delta;
if((Delta = NameLen + 1 + DateLen - 32) > 0)
Name[NameLen - Delta] = 0;
strcat(Name,"_");
strcat(Name,Date);
}
}
/* OpenAutoCaptureFile(STRPTR SomeName):
*
* Open a capture file.
*/
STATIC VOID __regargs
OpenAutoCaptureFile(STRPTR SomeName)
{
UBYTE SharedBuffer[MAX_FILENAME_LENGTH],
Name[50],
Date[20],
Time[20];
struct DateTime DateTime;
/* Get the current time and date. */
DateStamp(&DateTime . dat_Stamp);
/* Prepare for date conversion. */
DateTime . dat_Format = FORMAT_DOS;
DateTime . dat_Flags = 0;
DateTime . dat_StrDay = NULL;
DateTime . dat_StrDate = Date;
DateTime . dat_StrTime = Time;
/* Convert the date. */
if(DateToStr(&DateTime))
{
/* Remember the BBS name. */
strcpy(Name,SomeName);
/* Append the creation date if necessary. */
if(Config -> CaptureConfig -> AutoCaptureDate == AUTOCAPTURE_DATE_NAME)
BuildName(Name,Date);
/* Make it a reasonable name. */
FixName(Name);
/* Get the capture file path. */
strcpy(SharedBuffer,Config -> CaptureConfig -> CapturePath);
/* Try to build a valid file and path name. */
if(AddPart(SharedBuffer,Name,MAX_FILENAME_LENGTH))
{
/* Is the capture file still open? */
if(FileCapture)
{
/* Close the file. */
BufferClose(FileCapture);
FileCapture = NULL;
/* Any data written? */
if(!GetFileSize(CaptureName))
DeleteFile(CaptureName);
else
{
AddProtection(CaptureName,FIBF_EXECUTE);
if(Config -> MiscConfig -> CreateIcons)
AddIcon(CaptureName,FILETYPE_TEXT,TRUE);
}
}
/* Try to append the new data. */
if(FileCapture = BufferOpen(SharedBuffer,"a"))
{
/* Set the menu checkmark. */
CheckItem(MEN_CAPTURE_TO_FILE,TRUE);
/* Remember the current capture file name. */
strcpy(CaptureName,SharedBuffer);
/* Add the creation date if necessary. */
if(Config -> CaptureConfig -> AutoCaptureDate == AUTOCAPTURE_DATE_INCLUDE)
{
UBYTE DateTimeBuffer[256];
if(FormatStamp(&DateTime . dat_Stamp,NULL,NULL,DateTimeBuffer,FALSE))
BPrintf(FileCapture,LocaleString(MSG_DIALPANEL_FILE_CREATED_TXT),DateTimeBuffer);
}
}
else
CheckItem(MEN_CAPTURE_TO_FILE,FALSE);
ConOutputUpdate();
}
}
}
/* Connect(struct PhoneNode *DialNode,STRPTR NumberBuffer):
*
* Perform connect action(s).
*/
STATIC VOID __regargs
Connect(struct PhoneNode *DialNode,STRPTR NumberBuffer)
{
if(DialNode -> Entry)
{
UpdateConfig(DialNode -> Entry -> Config,Config);
ConfigChanged = FALSE;
MakeCall(DialNode -> Entry -> Header -> Name,NumberBuffer);
ObtainSemaphore(&PatternSemaphore);
ChosenPattern = FindTimeDate(PatternList,NumberBuffer);
SelectTime(DialNode -> Entry,ChosenPattern,NULL);
ChosenEntry = DialNode -> Entry;
WhichUnit = DT_FIRST_UNIT;
CurrentPay = 0;
SendStartup = TRUE;
ReleaseSemaphore(&PatternSemaphore);
strcpy(Password,DialNode -> Entry -> Header -> Password);
strcpy(UserName,DialNode -> Entry -> Header -> UserName);
strcpy(CurrentBBSName,DialNode -> Entry -> Header -> Name);
strcpy(CurrentBBSComment,DialNode -> Entry -> Header -> Comment);
strcpy(CurrentBBSNumber,NumberBuffer);
if(DialNode -> Entry -> Config && DialNode -> Entry -> Config -> ModemConfig)
{
OnlinePlus = DialNode -> Entry -> Config -> ModemConfig -> TimeToConnect;
if(DialNode -> Entry -> Config -> ModemConfig -> ConnectLimit > 0 && DialNode -> Entry -> Config -> ModemConfig -> ConnectLimitMacro[0])
{
LimitCount = DialNode -> Entry -> Config -> ModemConfig -> ConnectLimit;
strcpy(LimitMacro,DialNode -> Entry -> Config -> ModemConfig -> ConnectLimitMacro);
}
else
LimitCount = -1;
}
else
{
OnlinePlus = Config -> ModemConfig -> TimeToConnect;
if(Config -> ModemConfig -> ConnectLimit > 0 && Config -> ModemConfig -> ConnectLimitMacro[0])
{
LimitCount = Config -> ModemConfig -> ConnectLimit;
strcpy(LimitMacro,Config -> ModemConfig -> ConnectLimitMacro);
}
else
LimitCount = -1;
}
LogAction(LocaleString(MSG_DIALPANEL_CONNECTED_TO_1_TXT),DialNode -> Entry -> Header -> Name,NumberBuffer);
}
else
{
OnlinePlus = Config -> ModemConfig -> TimeToConnect;
MakeCall("???",NumberBuffer);
ObtainSemaphore(&PatternSemaphore);
ChosenPattern = FindTimeDate(PatternList,NumberBuffer);
SelectTime(NULL,ChosenPattern,NULL);
ChosenEntry = NULL;
ReleaseSemaphore(&PatternSemaphore);
CurrentPay = 0;
Password[0] = 0;
UserName[0] = 0;
SendStartup = FALSE;
CurrentBBSName[0] = 0;
CurrentBBSComment[0] = 0;
strcpy(CurrentBBSNumber,NumberBuffer);
if(Config -> ModemConfig -> ConnectLimit > 0 && Config -> ModemConfig -> ConnectLimitMacro[0])
{
LimitCount = Config -> ModemConfig -> ConnectLimit;
strcpy(LimitMacro,Config -> ModemConfig -> ConnectLimitMacro);
}
else
LimitCount = -1;
LogAction(LocaleString(MSG_DIALPANEL_CONNECTED_TO_2_TXT),NumberBuffer);
}
/* We are now online. */
ObtainSemaphore(&OnlineSemaphore);
Online = TRUE;
ReleaseSemaphore(&OnlineSemaphore);
/* Open auto-capture file. */
if(Config -> CaptureConfig -> ConnectAutoCapture && Config -> CaptureConfig -> CapturePath[0])
{
if(DialNode -> Entry)
OpenAutoCaptureFile(DialNode -> Entry -> Header -> Name);
else
OpenAutoCaptureFile(LocaleString(MSG_DIALPANEL_CAPTURE_NAME_TXT));
}
/* Remove node from
* dialing list and
* perform system
* setup.
*/
if(DialNode -> Entry)
RemoveDialNode(DialNode);
Remove(&DialNode -> VanillaNode);
FreeVecPooled(DialNode);
if(PrivateConfig -> MiscConfig -> BackupConfig)
{
if(!BackupConfig)
{
if(BackupConfig = CreateConfiguration(TRUE))
SaveConfig(PrivateConfig,BackupConfig);
}
}
/* Make sure that the following
* setup/initialization will not
* touch the serial configuration.
*/
memcpy(PrivateConfig -> SerialConfig,Config -> SerialConfig,sizeof(struct SerialSettings));
ConfigSetup();
/* Reset the scanner. */
FlowInit(TRUE);
}
/* OpenDialPanel(BOOL *Record):
*
* Open the dialing panel.
*/
STATIC LayoutHandle * __regargs
OpenDialPanel(BOOL *Record)
{
LayoutHandle *Handle;
if(Handle = LT_CreateHandleTags(Window -> WScreen,
LH_LocaleHook, &LocaleHook,
TAG_DONE))
{
LT_New(Handle,
LA_Type, VERTICAL_KIND,
TAG_DONE);
{
LT_New(Handle,
LA_Type, VERTICAL_KIND,
TAG_DONE);
{
LT_New(Handle,
LA_Type, VERTICAL_KIND,
TAG_DONE);
{
LT_New(Handle,
LA_Type, BOX_KIND,
LA_ID, GAD_CALLING,
LA_Chars, 45,
LA_Lines, 4,
LABX_ReserveSpace, TRUE,
LABX_FirstLabel, MSG_DIALPANEL_CALLING_TXT,
LABX_LastLabel, MSG_DIALPANEL_NEXT_TXT,
TAG_DONE);
LT_New(Handle,
LA_Type, BOX_KIND,
LA_ID, GAD_TIME,
LA_Chars, 45,
LA_Lines, 2,
LABX_ReserveSpace, TRUE,
LABX_FirstLabel, MSG_DIALPANEL_TIMEOUT_TXT,
LABX_LastLabel, MSG_DIALPANEL_ATTEMPT_TXT,
TAG_DONE);
LT_New(Handle,
LA_Type, BOX_KIND,
LA_ID, GAD_NOTE,
LA_Chars, 45,
LA_Lines, 1,
LABX_ReserveSpace, TRUE,
LABX_FirstLabel, MSG_DIALPANEL_MESSAGE_TXT,
LABX_LastLabel, MSG_DIALPANEL_MESSAGE_TXT,
TAG_DONE);
LT_EndGroup(Handle);
}
LT_New(Handle,
LA_Type, VERTICAL_KIND,
TAG_DONE);
{
LT_New(Handle,
LA_Type, XBAR_KIND,
TAG_DONE);
LT_New(Handle,
LA_Type, CHECKBOX_KIND,
LA_LabelID, MSG_DIALPANEL_RECORD_ON_CONNECTION_TXT,
LA_BOOL, Record,
TAG_DONE);
LT_EndGroup(Handle);
}
LT_EndGroup(Handle);
}
LT_New(Handle,
LA_Type,VERTICAL_KIND,
TAG_DONE);
{
LT_New(Handle,
LA_Type, XBAR_KIND,
LAXB_FullSize, TRUE,
TAG_DONE);
LT_EndGroup(Handle);
}
LT_New(Handle,LA_Type,HORIZONTAL_KIND,
LAGR_Spread, TRUE,
TAG_DONE);
{
LT_New(Handle,
LA_Type, BUTTON_KIND,
LA_LabelID, MSG_DIALPANEL_SKIP_GAD,
LA_ID, GAD_SKIP,
LABT_ExtraFat, TRUE,
GA_Disabled, TRUE,
TAG_DONE);
LT_New(Handle,
LA_Type, BUTTON_KIND,
LA_LabelID, MSG_GLOBAL_REMOVE_GAD,
LA_ID, GAD_REMOVE,
LABT_ExtraFat, TRUE,
GA_Disabled, TRUE,
TAG_DONE);
LT_New(Handle,
LA_Type, BUTTON_KIND,
LA_LabelID, MSG_DIALPANEL_GO_TO_ONLINE_GAD,
LA_ID, GAD_ONLINE,
LABT_ReturnKey, TRUE,
LABT_ExtraFat, TRUE,
TAG_DONE);
LT_New(Handle,
LA_Type, BUTTON_KIND,
LA_LabelID, MSG_GLOBAL_ABORT_GAD,
LA_ID, GAD_ABORT,
LABT_ExtraFat, TRUE,
TAG_DONE);
LT_EndGroup(Handle);
}
LT_EndGroup(Handle);
}
if(LT_Build(Handle,
LAWN_TitleID, MSG_DIALPANEL_DIALING_TXT,
LAWN_IDCMP, IDCMP_CLOSEWINDOW,
LAWN_HelpHook, &GuideHook,
LAWN_Parent, Window,
WA_DepthGadget, TRUE,
WA_CloseGadget, TRUE,
WA_DragBar, TRUE,
WA_RMBTrap, TRUE,
WA_Activate, TRUE,
WA_SimpleRefresh, TRUE,
TAG_DONE))
return(Handle);
else
LT_DeleteHandle(Handle);
}
return(NULL);
}
/* DialPanel():
*
* This routine opens a small window in the middle of the
* console window and walks down the list of numbers to
* dial.
*/
BOOL
DialPanel()
{
LayoutHandle *Handle;
BOOL Result = FALSE,
Record = FALSE,
DropIt = FALSE;
BlockWindows();
if(Handle = OpenDialPanel(&Record))
{
STATIC struct SerialSettings __far OriginalSerialConfig;
struct Window *PanelWindow = Handle -> Window;
UBYTE ExitCommand[80],
ExitBuffer[80],
InitBuffer[80],
PrefixBuffer[80],
NumberBuffer[100];
UBYTE DialBuffer[300];
STRPTR NextExit,
NextInit,
NextPrefix,
NextNumber;
WORD NumberCount,
NumberCurrent;
LONG DialTimeout,
DialRetries = 0,
DialAttempt = 0;
struct PhoneNode *DialNode = NULL;
LONG RedialTimeout;
STRPTR CallingName;
UBYTE CallingBuffer[80];
BOOL Dialing = FALSE,
Calling = FALSE,
Waiting = FALSE,
Skipping = FALSE,
Aborting = FALSE,
Error = FALSE,
Done = FALSE,
NeedHangUp = TRUE;
WORD RunCount = 0;
ULONG ODUMask;
// Don't mix up the line send stuff with the default sending routine
BYTE (* LocalSendLine)(register STRPTR,register LONG);
LocalSendLine = SendLine;
SendLine = SendLineDial;
// Set up the ODU stuff
if(OwnDevUnitBase && Config -> SerialConfig -> ReleaseODUWhenDialing && Config -> SerialConfig -> SatisfyODURequests != ODU_KEEP && !(Config -> SerialConfig -> Shared && Config -> SerialConfig -> NoODUIfShared) && OwnDevBit != -1)
ODUMask = (1L << OwnDevBit);
else
ODUMask = NULL;
/* Reset the area code scanner data. */
ObtainSemaphore(&PatternSemaphore);
ChosenEntry = NULL;
ChosenPattern = NULL;
ReleaseSemaphore(&PatternSemaphore);
/* We are now dialing. */
Status = STATUS_DIALING;
/* Remember the original serial settings, so we
* can return to them later.
*/
CopyMem(Config -> SerialConfig,&OriginalSerialConfig,sizeof(struct SerialSettings));
/* Set up the AmigaGuide help context. */
GuideContext(CONTEXT_DIAL);
/* No exit command is defined yet. */
ExitCommand[0] = 0;
/* Make the current one the active one. */
LT_ShowWindow(Handle,TRUE);
PushWindow(PanelWindow);
/* Make a backup of the current configuration. */
SaveConfig(Config,PrivateConfig);
/* Don't echo serial output unless requested by the user. */
if(!Config -> ModemConfig -> VerboseDialing)
Quiet = TRUE;
/* Perform full sequence check. */
FullCheck = TRUE;
/* Reset the scanner. */
FlowInit(TRUE);
/* Clear the signals. */
SetSignal(0,SIG_SKIP | SIG_BREAK);
/* The big dialing loop. */
do
{
/* Abort the process? */
if(SetSignal(0,SIG_BREAK) & SIG_BREAK)
{
if(!Done)
Aborting = Done = TRUE;
}
// Check if we should let go of the device
if(ODUMask)
{
if(SetSignal(0,0) & ODUMask)
{
if(!Done)
{
Aborting = Done = DropIt = TRUE;
SetSignal(0,ODUMask);
}
}
}
/* Any window input? */
if(!Done && (SetSignal(0,PORTMASK(PanelWindow -> UserPort)) & PORTMASK(PanelWindow -> UserPort)))
{
struct IntuiMessage *Msg;
ULONG MsgClass,
MsgQualifier;
UWORD MsgCode;
struct Gadget *MsgGadget;
while(Msg = LT_GetIMsg(Handle))
{
MsgClass = Msg -> Class;
MsgCode = Msg -> Code;
MsgQualifier = Msg -> Qualifier;
MsgGadget = Msg -> IAddress;
LT_ReplyIMsg(Msg);
/* Convert the space keypress into a
* skip command.
*/
if(MsgClass == IDCMP_RAWKEY)
{
if((Dialing || Waiting) && LT_GetCode(MsgQualifier,MsgClass,MsgCode,MsgGadget) == ' ')
{
LT_PressButton(Handle,GAD_SKIP);
Skipping = TRUE;
}
}
/* Close the window, hang up the line,
* return to the phone book.
*/
if(MsgClass == IDCMP_CLOSEWINDOW)
Aborting = Done = Result = TRUE;
/* So a button was pressed. */
if(MsgClass == IDCMP_GADGETUP)
{
switch(MsgGadget -> GadgetID)
{
/* Remove the currently active dialing
* list entry.
*/
case GAD_REMOVE:
/* This makes sense only while
* we are dialing.
*/
if(Dialing)
{
struct PhoneNode *NextNode = NULL;
BOOL UseHangUp;
/* If still dialing, hang up first. */
if(DialNode -> Entry && DialNode -> Entry -> Config && DialNode -> Entry -> Config -> ModemConfig)
UseHangUp = DialNode -> Entry -> Config -> ModemConfig -> AbortHangsUp;
else
UseHangUp = Config -> ModemConfig -> AbortHangsUp;
if(UseHangUp)
HangUp();
else
{
SerWrite("\r",1);
WaitTime(1,0);
}
/* Ignore the response of the modem. */
HandleSerial();
FlowInit(TRUE);
/* Is there another entry in the list? */
if(DialNode -> VanillaNode . ln_Succ -> ln_Succ)
NextNode = (struct PhoneNode *)DialNode -> VanillaNode . ln_Succ;
else
{
/* No, there isn't; do we have a list with
* at least two entries in it?
*/
if(DialList -> lh_Head -> ln_Succ -> ln_Succ)
{
/* Yet another dialing attempt coming up... */
DialAttempt++;
/* Check for dial retry limit. */
if(DialRetries >= 0 && DialAttempt >= DialRetries)
{
PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_MAXIMUM_NUMBER_OF_DIAL_RETRIES_TXT));
WakeUp(PanelWindow,SOUND_BELL);
WaitTime(2,0);
Say(LocaleString(MSG_DIALPANEL_MAXIMUM_NUMBER_OF_DIAL_RETRIES_TXT));
Done = TRUE;
}
else
{
/* Grab first list entry and continue. */
NextNode = (struct PhoneNode *)DialList -> lh_Head;
}
}
else
{
/* That's all, folks! */
PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_DIALING_LIST_IS_EMPTY_TXT));
WaitTime(2,0);
Done = TRUE;
}
}
/* Remove dial entry from list. */
if(DialNode -> Entry)
RemoveDialNode(DialNode);
Remove(&DialNode -> VanillaNode);
FreeVecPooled(DialNode);
/* Is there an entry to proceed with? */
if(DialNode = NextNode)
{
NextNumber = NULL;
Calling = TRUE;
}
}
break;
case GAD_SKIP:
if(Dialing || Waiting)
Skipping = TRUE;
break;
case GAD_ONLINE:
/* Go online so soon? */
if(!DialNode)
{
DialNode = (struct PhoneNode *)DialList -> lh_Head;
if(DialNode -> Entry)
ExtractString(DialNode -> Entry -> Header -> Number,NumberBuffer,TRUE);
else
ExtractString(DialNode -> VanillaNode . ln_Name,NumberBuffer,TRUE);
}
Connect(DialNode,NumberBuffer);
Done = TRUE;
break;
/* Abort the dialing process. */
case GAD_ABORT:
Aborting = Done = TRUE;
break;
}
}
if(Done)
break;
}
}
/* Skip the current action? */
if(SetSignal(0,SIG_SKIP) & SIG_SKIP)
{
if((Dialing || Waiting) && !Done)
Skipping = TRUE;
}
/* Are we to abort? */
if(Aborting)
{
/* Hang up if necessary. */
if(Dialing)
{
BOOL UseHangUp;
PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_ABORTING_TXT));
if(DialNode -> Entry && DialNode -> Entry -> Config && DialNode -> Entry -> Config -> ModemConfig)
UseHangUp = DialNode -> Entry -> Config -> ModemConfig -> AbortHangsUp;
else
UseHangUp = Config -> ModemConfig -> AbortHangsUp;
if(UseHangUp)
HangUp();
else
{
SerWrite("\r",1);
WaitTime(1,0);
}
/* Ignore the response of the modem. */
HandleSerial();
FlowInit(TRUE);
}
}
/* Start at the beginning. */
if(!DialNode && !Done)
{
DialNode = (struct PhoneNode *)DialList -> lh_Head;
LT_SetAttributes(Handle,GAD_SKIP,
GA_Disabled, FALSE,
TAG_DONE);
LT_SetAttributes(Handle,GAD_REMOVE,
GA_Disabled, FALSE,
TAG_DONE);
Calling = TRUE;
NextNumber = NULL;
}
/* Are we to start a call? */
if(Calling && !Done)
{
/* Reset the sequence scanner, the user may have skipped
* the previous dial attempt causing the modem to return
* `NO CARRIER'. To prevent the dialer from skipping the
* next dial entry as well as the previous we have to
* flush any data pending on the serial line.
*/
FlowInit(TRUE);
/* Is this the first number for this dial entry? */
if(!NextNumber)
{
STRPTR PhoneNumber;
WORD i,Len;
/* Does this entry have a configuration attached? */
if(DialNode -> Entry)
{
/* Get the phone number. */
PhoneNumber = DialNode -> Entry -> Header -> Number;
/* Pick up the modem configuration. */
if(DialNode -> Entry -> Config -> ModemConfig)
{
NextInit = ExtractString(DialNode -> Entry -> Config -> ModemConfig -> ModemInit, InitBuffer, FALSE);
NextExit = ExtractString(DialNode -> Entry -> Config -> ModemConfig -> ModemExit, ExitBuffer, FALSE);
NextPrefix = ExtractString(DialNode -> Entry -> Config -> ModemConfig -> DialPrefix, PrefixBuffer, FALSE);
}
else
{
NextInit = ExtractString(Config -> ModemConfig -> ModemInit, InitBuffer, FALSE);
NextExit = ExtractString(Config -> ModemConfig -> ModemExit, ExitBuffer, FALSE);
NextPrefix = ExtractString(Config -> ModemConfig -> DialPrefix, PrefixBuffer, FALSE);
}
}
else
{
/* Get the phone number. */
PhoneNumber = DialNode -> VanillaNode . ln_Name;
/* Pick up the modem configuration. */
if(Config -> ModemConfig -> DoNotSendMainModemCommands)
InitBuffer[0] = ExitBuffer[0] = 0;
else
{
NextInit = ExtractString(Config -> ModemConfig -> ModemInit, InitBuffer, FALSE);
NextExit = ExtractString(Config -> ModemConfig -> ModemExit, ExitBuffer, FALSE);
}
NextPrefix = ExtractString(Config -> ModemConfig -> DialPrefix, PrefixBuffer, FALSE);
}
/* Extract the phone number. */
NextNumber = ExtractString(PhoneNumber,NumberBuffer,TRUE);
/* Count the number of phone numbers separated
* by "|" characters.
*/
Len = strlen(PhoneNumber);
for(i = 0, NumberCount = 0 ; i < Len ; i++)
{
if(PhoneNumber[i] == '|')
{
WORD j;
for(j = i + 1 ; j <= Len ; j++)
{
if(PhoneNumber[j] != ' ' && PhoneNumber[j] != 0)
{
if(PhoneNumber[j] != '|')
NumberCount++;
break;
}
}
}
}
/* This is the first one. */
NumberCurrent = 0;
}
else
{
/* Now for multiple phone numbers separated
* by `|' characters. If `NextNumber' happens
* to be zero, we will prepare to extract
* the first phone number from the list.
* In any other case we will try to obtain
* the next number.
*/
NextNumber = ExtractString(NextNumber, NumberBuffer, TRUE);
NextPrefix = ExtractString(NextPrefix, PrefixBuffer, FALSE);
if(!DialNode -> Entry && Config -> ModemConfig -> DoNotSendMainModemCommands)
InitBuffer[0] = ExitBuffer[0] = 0;
else
{
NextInit = ExtractString(NextInit, InitBuffer, FALSE);
NextExit = ExtractString(NextExit, ExitBuffer, FALSE);
}
NumberCurrent++;
}
/* Send the modem exit string before we
* will need to reconfigure the serial
* device driver.
*/
if(ExitCommand[0])
Error |= Done |= SendSomeCommand(Handle,ExitCommand,LocaleString(MSG_DIALPANEL_SENDING_MODEM_EXIT_COMMAND_TXT),LocaleString(MSG_DIALPANEL_ERROR_SENDING_MODEM_COMMAND_TXT));
/* We will need to change the serial parameters
* in order to establish a connection.
*/
if(!Done)
{
if(DialNode -> Entry && DialNode -> Entry -> Config -> SerialConfig)
{
if(ReconfigureSerial(PanelWindow,DialNode -> Entry -> Config -> SerialConfig) == RECONFIGURE_FAILURE)
{
WakeUp(PanelWindow,SOUND_ERROR);
Error = Done = TRUE;
}
}
else
{
if(ReconfigureSerial(PanelWindow,&OriginalSerialConfig) == RECONFIGURE_FAILURE)
{
WakeUp(PanelWindow,SOUND_ERROR);
Error = Done = TRUE;
}
}
}
if(!Done)
{
// Update the ODU stuff
if(OwnDevUnitBase && Config -> SerialConfig -> ReleaseODUWhenDialing && Config -> SerialConfig -> SatisfyODURequests != ODU_KEEP && !(Config -> SerialConfig -> Shared && Config -> SerialConfig -> NoODUIfShared) && OwnDevBit != -1)
ODUMask = (1L << OwnDevBit);
else
ODUMask = NULL;
/* Send the modem init command. */
if(InitBuffer[0])
Error |= Done |= SendSomeCommand(Handle,InitBuffer,LocaleString(MSG_DIALPANEL_SENDING_MODEM_INIT_COMMAND_TXT),LocaleString(MSG_DIALPANEL_ERROR_SENDING_MODEM_COMMAND_TXT));
}
if(!Done)
{
/* Remember the new exit command. */
strcpy(ExitCommand,ExitBuffer);
if(DialNode -> Entry)
CallingName = DialNode -> Entry -> Header -> Name;
else
CallingName = LocaleString(MSG_GLOBAL_UNKNOWN_TXT);
/* If there is more than one number to follow, say so. */
if(NumberCount)
{
UBYTE LocalBuffer[40];
SPrintf(LocalBuffer,LocaleString(MSG_DIALPANEL_ATTEMPT_OF_TXT),NumberCurrent + 1,NumberCount + 1);
SPrintf(CallingBuffer,"%s (%s)",CallingName,LocalBuffer);
CallingName = CallingBuffer;
}
PrintBox(Handle,GAD_CALLING,0,CallingName);
/* Show the comment if any. */
if(DialNode -> Entry && DialNode -> Entry -> Header -> Comment[0])
PrintBox(Handle,GAD_CALLING,1,DialNode -> Entry -> Header -> Comment);
else
PrintBox(Handle,GAD_CALLING,1,"-");
/* Display the number being called. */
if(DialNode -> Entry)
Say(LocaleString(MSG_DIALPANEL_NOW_CALLING_TXT),DialNode -> Entry -> Header -> Name);
else
Say(LocaleString(MSG_DIALPANEL_NOW_CALLING_TXT),NumberBuffer);
PrintBox(Handle,GAD_CALLING,2,NumberBuffer);
/* Display the name of the service to call next. */
if(NextNumber)
{
if(DialNode -> Entry)
CallingName = DialNode -> Entry -> Header -> Name;
else
CallingName = DialNode -> VanillaNode . ln_Name;
}
else
{
if(DialNode -> VanillaNode . ln_Succ -> ln_Succ)
{
if(DialNode -> Entry)
CallingName = ((struct PhoneNode *)DialNode -> VanillaNode . ln_Succ) -> Entry -> Header -> Name;
else
CallingName = DialNode -> VanillaNode . ln_Succ -> ln_Name;
}
else
CallingName = "-";
}
PrintBox(Handle,GAD_CALLING,3,CallingName);
/* Right now we're dialing. */
PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_DIALING_TXT));
/* Build the dialing command. */
strcpy(DialBuffer,PrefixBuffer);
if(DialNode -> Entry && DialNode -> Entry -> Config -> ModemConfig)
{
if(DialNode -> Entry -> Config -> ModemConfig -> PBX_Mode && DialNode -> Entry -> Config -> ModemConfig -> PBX_Prefix[0])
strcat(DialBuffer,DialNode -> Entry -> Config -> ModemConfig -> PBX_Prefix);
}
else
{
if(Config -> ModemConfig -> PBX_Mode && Config -> ModemConfig -> PBX_Prefix[0])
strcat(DialBuffer,Config -> ModemConfig -> PBX_Prefix);
}
strcat(DialBuffer,NumberBuffer);
if(DialNode -> Entry)
{
if(DialNode -> Entry -> Config -> ModemConfig)
strcat(DialBuffer,DialNode -> Entry -> Config -> ModemConfig -> DialSuffix);
else
strcat(DialBuffer,Config -> ModemConfig -> DialSuffix);
}
else
strcat(DialBuffer,Config -> ModemConfig -> DialSuffix);
/* Pick up dial timeout and dial retries. */
if(DialNode -> Entry && DialNode -> Entry -> Config -> ModemConfig)
{
DialTimeout = DialNode -> Entry -> Config -> ModemConfig -> DialTimeout;
DialRetries = DialNode -> Entry -> Config -> ModemConfig -> DialRetries;
}
else
{
DialTimeout = Config -> ModemConfig -> DialTimeout;
DialRetries = Config -> ModemConfig -> DialRetries;
}
/* Dial the number. */
SerialCommand(DialBuffer);
/* Now we should be dialing. */
Calling = FALSE;
Dialing = TRUE;
/* For the sake of precision. */
RunCount = 0;
}
}
/* Are we to skip the current assignment? */
if(Skipping && !Done)
{
Skipping = FALSE;
/* Are we currently dialing? */
if(Dialing)
{
/* Hang up if necessary. */
if(NeedHangUp)
{
BOOL UseHangUp;
if(DialNode -> Entry && DialNode -> Entry -> Config && DialNode -> Entry -> Config -> ModemConfig)
UseHangUp = DialNode -> Entry -> Config -> ModemConfig -> AbortHangsUp;
else
UseHangUp = Config -> ModemConfig -> AbortHangsUp;
if(UseHangUp)
HangUp();
else
{
SerWrite("\r",1);
WaitTime(1,0);
}
}
else
NeedHangUp = TRUE;
/* Ignore the response of the modem. */
HandleSerial();
FlowInit(TRUE);
/* Did we dial all the numbers available? */
if(!NextNumber)
{
/* Is this one the last entry? */
if(DialNode -> VanillaNode . ln_Succ -> ln_Succ)
{
LONG InterDialDelay;
/* There is still another entry. */
DialNode = (struct PhoneNode *)DialNode -> VanillaNode . ln_Succ;
/* Get the inter-dial delay. */
if(DialNode -> Entry)
{
if(DialNode -> Entry -> Config -> ModemConfig)
InterDialDelay = DialNode -> Entry -> Config -> ModemConfig -> InterDialDelay;
else
InterDialDelay = Config -> ModemConfig -> InterDialDelay;
}
else
InterDialDelay = Config -> ModemConfig -> InterDialDelay;
/* Check if we should wait before we fire off another dial command. */
if(InterDialDelay)
{
/* Wait until the inter-dial delay has elapsed. */
RedialTimeout = InterDialDelay;
PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_WAITING_TO_CALL_TXT));
Dialing = FALSE;
Waiting = TRUE;
/* For the sake of precision. */
RunCount = 0;
Say(LocaleString(MSG_DIALPANEL_WAITING_TXT));
/* No entry is currently being called. */
PrintBox(Handle,GAD_CALLING,0,"-");
PrintBox(Handle,GAD_CALLING,1,"-");
PrintBox(Handle,GAD_CALLING,2,"-");
LT_SetAttributes(Handle,GAD_REMOVE,
GA_Disabled, TRUE,
TAG_DONE);
/* Display name of entry to call next. */
if(DialNode -> Entry)
PrintBox(Handle,GAD_CALLING,3,DialNode -> Entry -> Header -> Name);
else
PrintBox(Handle,GAD_CALLING,3,LocaleString(MSG_GLOBAL_UNKNOWN_TXT));
}
else
{
Dialing = FALSE;
Calling = TRUE;
}
}
else
{
/* Yet another dial attempt coming up. */
DialAttempt++;
/* Is this one the last dial
* attempt to be made?
*/
if(DialAttempt >= DialRetries && DialRetries >= 0)
{
PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_MAXIMUM_NUMBER_OF_DIAL_RETRIES_TXT));
WakeUp(PanelWindow,SOUND_BELL);
WaitTime(2,0);
Say(LocaleString(MSG_DIALPANEL_MAXIMUM_NUMBER_OF_DIAL_RETRIES_TXT));
Done = TRUE;
}
else
{
LONG InterDialDelay;
/* Get the first list entry. */
DialNode = (struct PhoneNode *)DialList -> lh_Head;
NextNumber = NULL;
/* Get the redial delay. */
if(DialNode -> Entry)
{
if(DialNode -> Entry -> Config -> ModemConfig)
{
RedialTimeout = DialNode -> Entry -> Config -> ModemConfig -> RedialDelay;
InterDialDelay = DialNode -> Entry -> Config -> ModemConfig -> InterDialDelay;
}
else
{
RedialTimeout = Config -> ModemConfig -> RedialDelay;
InterDialDelay = Config -> ModemConfig -> InterDialDelay;
}
}
else
{
RedialTimeout = Config -> ModemConfig -> RedialDelay;
InterDialDelay = Config -> ModemConfig -> InterDialDelay;
}
/* Check if the inter-dial delay is larger than
* the redial delay. If so, use the inter-dial delay.
*/
if(InterDialDelay > RedialTimeout)
RedialTimeout = InterDialDelay;
/* No redial delay? Restart dialing... */
if(!RedialTimeout)
{
Dialing = FALSE;
Calling = TRUE;
WaitTime(1,0);
}
else
{
/* Go into redial delay. */
PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_REDIAL_DELAY_TXT));
Dialing = FALSE;
Waiting = TRUE;
/* For the sake of precision. */
RunCount = 0;
Say(LocaleString(MSG_DIALPANEL_WAITING_TXT));
/* No entry is currently being called. */
PrintBox(Handle,GAD_CALLING,0,"-");
PrintBox(Handle,GAD_CALLING,1,"-");
PrintBox(Handle,GAD_CALLING,2,"-");
LT_SetAttributes(Handle,GAD_REMOVE,
GA_Disabled, TRUE,
TAG_DONE);
/* Display name of entry to call next. */
if(DialNode -> Entry)
PrintBox(Handle,GAD_CALLING,3,DialNode -> Entry -> Header -> Name);
else
PrintBox(Handle,GAD_CALLING,3,LocaleString(MSG_GLOBAL_UNKNOWN_TXT));
}
}
}
}
else
{
LONG InterDialDelay;
/* Get the inter-dial delay. */
if(DialNode -> Entry)
{
if(DialNode -> Entry -> Config -> ModemConfig)
InterDialDelay = DialNode -> Entry -> Config -> ModemConfig -> InterDialDelay;
else
InterDialDelay = Config -> ModemConfig -> InterDialDelay;
}
else
InterDialDelay = Config -> ModemConfig -> InterDialDelay;
/* Check if we should wait before we fire off another dial command. */
if(InterDialDelay)
{
/* Wait until the inter-dial delay has elapsed. */
RedialTimeout = InterDialDelay;
PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_WAITING_TO_CALL_TXT));
Dialing = FALSE;
Waiting = TRUE;
/* For the sake of precision. */
RunCount = 0;
Say(LocaleString(MSG_DIALPANEL_WAITING_TXT));
/* No entry is currently being called. */
PrintBox(Handle,GAD_CALLING,0,"-");
PrintBox(Handle,GAD_CALLING,1,"-");
PrintBox(Handle,GAD_CALLING,2,"-");
LT_SetAttributes(Handle,GAD_REMOVE,
GA_Disabled, TRUE,
TAG_DONE);
/* Display name of entry to call next. */
if(DialNode -> Entry)
PrintBox(Handle,GAD_CALLING,3,DialNode -> Entry -> Header -> Name);
else
PrintBox(Handle,GAD_CALLING,3,LocaleString(MSG_GLOBAL_UNKNOWN_TXT));
}
else
{
Dialing = FALSE;
Calling = TRUE;
}
}
}
else
{
/* Stop waiting. */
if(Waiting)
{
LT_SetAttributes(Handle,GAD_REMOVE,
GA_Disabled, FALSE,
TAG_DONE);
Waiting = FALSE;
Calling = TRUE;
}
}
}
/* Take care of serial input. */
if(!Done)
HandleSerial();
/* Any news from the modem? */
if(!Done && FlowInfo . Changed)
{
/* Current number is busy. */
if(FlowInfo . Busy || (FlowInfo . NoCarrier && Config -> ModemConfig -> NoCarrierIsBusy))
{
FlowInit(TRUE);
if(Dialing && !Done)
{
PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_LINE_IS_BUSY_TXT));
Say(LocaleString(MSG_DIALPANEL_LINE_IS_BUSY_TXT));
WaitTime(1,0);
Skipping = TRUE;
NeedHangUp = FALSE;
}
}
/* Line does not feature a dialtone. */
if(FlowInfo . NoDialTone)
{
FlowInit(TRUE);
if(Dialing && !Done)
{
PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_NO_DIALTONE_TXT));
WakeUp(PanelWindow,SOUND_ERROR);
Say(LocaleString(MSG_DIALPANEL_NO_DIALTONE_TXT));
Error = Done = TRUE;
}
}
/* Somebody tries to call us. */
if(FlowInfo . Ring)
{
FlowInit(TRUE);
if(!Done)
{
PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_GLOBAL_INCOMING_CALL_TXT));
WakeUp(PanelWindow,SOUND_RING);
Say(LocaleString(MSG_GLOBAL_INCOMING_CALL_TXT));
Error = Done = TRUE;
}
}
/* Somebody's talking. */
if(FlowInfo . Voice)
{
FlowInit(TRUE);
if(!Done)
{
PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_INCOMING_VOICE_CALL_TXT));
WakeUp(PanelWindow,SOUND_VOICE);
Say(LocaleString(MSG_DIALPANEL_INCOMING_VOICE_CALL_TXT));
Error = Done = TRUE;
}
}
/* We got a connect. */
if(FlowInfo . Connect)
{
FlowInit(TRUE);
if(Dialing && !Done)
{
/* Make the connection. */
Connect(DialNode,NumberBuffer);
Done = TRUE;
/* Wake the user up. */
if(BaudBuffer[0])
{
PrintBox(Handle,GAD_NOTE,0,"CONNECT %s",BaudBuffer);
WakeUp(PanelWindow,SOUND_CONNECT);
WaitTime(2,0);
/* Install new baud rate if desired. */
if(Config -> ModemConfig -> ConnectAutoBaud && DTERate > 110)
{
Config -> SerialConfig -> BaudRate = DTERate;
ReconfigureSerial(PanelWindow,NULL);
}
}
else
{
PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_CONNECTION_ESTABLISHED_TXT));
WakeUp(PanelWindow,SOUND_CONNECT);
}
Say(LocaleString(MSG_DIALPANEL_CONNECTION_ESTABLISHED_TXT));
}
}
/* Looks like an error. */
if(FlowInfo . Error)
{
FlowInit(TRUE);
if(Dialing && !Done)
{
PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_ERROR_SENDING_MODEM_COMMAND_TXT));
WakeUp(PanelWindow,SOUND_ERROR);
Error = Done = TRUE;
}
}
/* In any other case, reset the scanner. */
FlowInit(TRUE);
}
/* If nothing special's up... */
if(!Done && !Skipping && (Dialing || Waiting))
{
/* Wait half a second. */
WaitTime(0,MILLION / 2);
if(Dialing)
{
PrintBox(Handle,GAD_TIME,0,"%2ld:%02ld",DialTimeout / 60,DialTimeout % 60);
if(DialRetries < 0)
PrintBox(Handle,GAD_TIME,1,LocaleString(MSG_DIAL_RETRIES_UNLIMITED_TXT));
else
PrintBox(Handle,GAD_TIME,1,LocaleString(MSG_DIALPANEL_ATTEMPT_OF_TXT),DialAttempt + 1,DialRetries);
}
if(Waiting)
PrintBox(Handle,GAD_TIME,0,"%2ld:%02ld",RedialTimeout / 60,RedialTimeout % 60);
/* The following instructions are executed each second */
if(RunCount++)
{
RunCount = 0;
/* Are we dialing? */
if(Dialing)
{
/* Yet another second has elapsed. */
if(DialTimeout > 0)
DialTimeout--;
/* Has the dial timeout elapsed without
* a connection being made?
*/
if(!DialTimeout)
{
PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_DIAL_ATTEMPT_TIMEOUT_TXT));
Skipping = TRUE;
}
}
/* Are we waiting? */
if(Waiting)
{
/* Yet another second has elapsed. */
if(RedialTimeout > 0)
RedialTimeout--;
/* The redial delay has elapsed,
* start dialing again.
*/
if(!RedialTimeout)
Skipping = TRUE;
}
}
}
}
while(!Done);
/* Are we online or not? */
ObtainSemaphore(&OnlineSemaphore);
if(!Online)
{
BOOL SendCommands = TRUE;
ReleaseSemaphore(&OnlineSemaphore);
/* Is the serial setup different? */
if(memcmp(Config -> SerialConfig,&OriginalSerialConfig,sizeof(struct SerialSettings)))
{
/* Set up the old serial configuration. */
if(ReconfigureSerial(PanelWindow,&OriginalSerialConfig) == RECONFIGURE_FAILURE)
SendCommands = FALSE;
}
if(SendCommands)
{
/* Send the exit command if necessary. */
if(ExitCommand[0])
Error |= SendSomeCommand(Handle,ExitCommand,LocaleString(MSG_DIALPANEL_SENDING_MODEM_EXIT_COMMAND_TXT),LocaleString(MSG_DIALPANEL_ERROR_SENDING_MODEM_COMMAND_TXT));
/* Take care of the init command if necessary. */
if(Config -> ModemConfig -> ModemInit[0] && !Error)
Error |= SendSomeCommand(Handle,Config -> ModemConfig -> ModemInit,LocaleString(MSG_DIALPANEL_SENDING_MODEM_INIT_COMMAND_TXT),LocaleString(MSG_DIALPANEL_ERROR_SENDING_MODEM_COMMAND_TXT));
}
}
else
ReleaseSemaphore(&OnlineSemaphore);
/* Make sure the error gets displayed. */
if(Error && !DropIt)
{
struct IntuiMessage *Msg;
ULONG MsgClass;
WORD i;
for(i = GAD_SKIP ; i <= GAD_REMOVE ; i++)
LT_SetAttributes(Handle,i,GA_Disabled,TRUE,TAG_DONE);
Done = FALSE;
do
{
if(Wait(PORTMASK(PanelWindow -> UserPort) | SIG_BREAK) & SIG_BREAK)
break;
while(Msg = LT_GetIMsg(Handle))
{
MsgClass = Msg -> Class;
LT_ReplyIMsg(Msg);
if(MsgClass == IDCMP_CLOSEWINDOW || MsgClass == IDCMP_GADGETUP)
Done = TRUE;
}
}
while(!Done);
}
// Put back the old routine if necessary
if(SendLine == SendLineDial)
SendLine = LocalSendLine;
PopWindow();
LT_DeleteHandle(Handle);
/* Reset the scanner. */
FullCheck = FALSE;
FlowInit(TRUE);
/* We are done now, restart echoing serial */
Quiet = FALSE;
ReleaseWindows();
/* Reset the display if necessary. */
if(ResetDisplay)
{
if(!DisplayReset())
return(FALSE);
}
/* Handle online jobs. */
ObtainSemaphore(&OnlineSemaphore);
if(Online)
{
ReleaseSemaphore(&OnlineSemaphore);
SetDialMenu(FALSE);
/* Send the startup macro if necessary. */
if(SendStartup)
{
if(Config -> CommandConfig -> LoginMacro[0])
SerialCommand(Config -> CommandConfig -> LoginMacro);
if(Config -> CommandConfig -> StartupMacro[0])
SerialCommand(Config -> CommandConfig -> StartupMacro);
SendStartup = FALSE;
}
/* Take care of the recording feature. */
if(Record)
{
if(CreateRecord(CurrentBBSName[0] ? CurrentBBSName : CurrentBBSNumber))
{
RememberResetOutput();
RememberResetInput();
RememberOutput = TRUE;
Recording = TRUE;
RecordingLine = FALSE;
OnItem(MEN_RECORD_LINE);
CheckItem(MEN_RECORD,TRUE);
CheckItem(MEN_RECORD_LINE,FALSE);
}
}
}
else
{
ReleaseSemaphore(&OnlineSemaphore);
SetDialMenu(TRUE);
}
}
else
ReleaseWindows();
/* Reply to the message that started the
* dialing process.
*/
ObtainSemaphore(&OnlineSemaphore);
Forbid();
if(DialMsg)
{
if(Online)
DialMsg -> rm_Result1 = RC_OK;
else
DialMsg -> rm_Result1 = RC_WARN;
DialMsg -> rm_Result2 = 0;
ReplyMsg(DialMsg);
DialMsg = NULL;
}
Permit();
ReleaseSemaphore(&OnlineSemaphore);
if(DropIt)
HandleOwnDevUnit();
return(Result);
}